#!/usr/bin/perl -w
# configure_ejabberd.pm
# Copyright (C) 2006  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

#
# For more information: http://carrierclass.net/
#
use strict; use warnings;

package CCNCore::Provision::Application::ejabberd;
use base qw(CCNCore::Provision::Base);

use CCN::Text;
use CCNCore::Scripting;
use CCNCore::Home;

our $restart = '/etc/init.d/ejabberd stop; /usr/bin/killall -u ejabberd; /usr/bin/killall epmd; /bin/rm /var/log/ejabberd/*; /bin/rm /var/lib/ejabberd/*; /bin/rm /var/lib/ejabberd/.erlang.cookie; export HOME=/var/lib/ejabberd; /bin/chown ejabberd.ejabberd /var/lib/ejabberd/; /etc/init.d/ejabberd start && /bin/sleep 15; ';

sub run()
{
    my $self = shift;

    # Server side

    $self->PACKAGE ('ejabberd');
    $self->CHECKFOR ('/etc/init.d/ejabberd');
    $self->CHECKFOR ('/etc/ejabberd');
    
    # For now, only the first cdn_downstream_server for a system is used as a Jabber server.
    # (Need to figure out how to build a Jabber cluster before we can have more.)
    # (Hopefully the Perl XMPP modules can do SRV failover.)
    my $server_pk = $self->sql_get(<<'SQL',$self->p->system_pk);
        SELECT MIN(cdn_downstream_server) FROM server WHERE the_system = ?
SQL

    $self->disable('ejabberd'),
    return
        unless $self->p->server_pk == $server_pk;

    $self->enable('ejabberd');

    if($self->upgrading)
    {
        CCN::Scripting::exec_command(CCNCore::Home::manager.'/bin/provision/install-ejabberd-pem.sh');
    }

    for my $f1 ('/etc/default/ejabberd')
    {
        my $short = $self->p->server_name;
        $short =~ s/^([^.]+)\..*$/$1/;

        # Comment in unstable's:
    
        # The next variable allows to explicitly specify erlang node for ejabberd
        # It can be given in different formats:
        # ERLANG_NODE=ejabberd
        # Lets erlang add hostname to the node (ejabberd uses short name in this case)
        # ERLANG_NODE=ejabberd@hostname
        # Erlang uses node name as is (so make sure that hostname is a real machine
        # hostname or you'll not be able to control ejabberd)
        # ERLANG_NODE=ejabberd@hostname.domainname
        # The same as previous, but erlang will use long hostname (see erl (1) manual for details)
        #

        CAT $f1, <<"EOT";
export ERL_OPTIONS="-heart"
export ERL_MAX_PORTS=1024
export ERL_FULLSWEEP_AFTER=3600
# Note: The Debian /usr/sbin/ejabberd will start erlang in non-clustered mode (-sname)
#       if ERLANG_NODE does not contain a ".".
#       Ejabberd doesn't start with -name in etch (erlang starts and uses the FQDN,
#       but a couple components complain about illegal hostname).
#       TBD What if the hostname changes? Hugh.
export ERLANG_NODE=node${short}
EOT
    }

    # How to check config:
    # erl ..
    #   file:consult("/etc/ejabberd/ejabberd.cfg").
    # Proper way to start from command line:
    #    su ejabberd -c /usr/sbin/ejabberd

    my $SALT = $self->system_salt;

    my $env = {
        'SERVER'   => $self->p->server_name,
        'SYSNAME'  => $self$self->p->system_name,
        'PORT'     => 5222,
    };

    for my $f2 ('/etc/ejabberd/ejabberd.cfg')
    {
        my $cfg = template_text( content_of(CCNCore::Home::manager.'/lib/templates/ejabberd.cfg'), $env );
        CAT $f2, $cfg;
    }

    COMMIT_MODULE(ref($self));
}

sub commit()
{
    my $self = shift;
    my $c    = shift;

    for my $f2 ('/etc/ejabberd/ejabberd.cfg')
    {
        $c->run_if_changed($f2, $restart);
    }

    CCN::Scripting::exec_command("/usr/sbin/ejabberdctl status || { $restart }");

    # Create the usernames for the different servers in the system.
    my $SALT = $self->system_salt;

    $self->sql_do_for(<<'SQL',$self->p->system_pk,
        SELECT pk FROM server WHERE system = ?
SQL
    sub
    {
        my $client_pk = shift;
        
        my $env = {
            'DOMAIN'    => $self$self->p->system_name,
            'SERVER'    => $self->p->server_name,
            'LOGIN'     => 's'.$client_pk,
            'PASSWORD'  => $self->make_password($client_pk,$SALT,'spool'),
        };
        my $unregister_cmd = template_text "/usr/sbin/ejabberdctl unregister _{LOGIN}_ _{SERVER}_", $env;
        my $register_cmd   = template_text "/usr/sbin/ejabberdctl register   _{LOGIN}_ _{SERVER}_ _{PASSWORD}_", $env;
        $self->log(template_text "Registering  _{LOGIN}_ _{SERVER}_ _{PASSWORD}_\n", $env);
        CCN::Scripting::exec_command("$unregister_cmd; $register_cmd || echo Failed");
    });
}

1;
